#include "widget.h"
#include "ui_widget.h"
#include <QSerialPortInfo>
#include <QMessageBox>
#include <QString>
#include <QPushButton>
#include <QDebug>
#include <string>
#include <QByteArray>
#include <QTimer>//包含QTimer头文件


Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    // 定义一个文件指针
    FILE *file_fd;
    //实例化一个串口对象
    serialport = new QSerialPort(this);
    //存放扫描到的串口设备名
    QStringList serialNumPort;
    //手动关联串口接收数据信号和自己定义串口接收数据槽函数
    connect(serialport,SIGNAL(readyRead()),this,SLOT(serialReadData_slot()));
    //循环扫描设备上的串口设备
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        serialNumPort << info.portName();
    }
    ui->serialCb->addItems(serialNumPort);
    // 打开当前目录下voltage.txt 若没有则创建 "w+"打开-清除-（创建）
    file_fd = fopen("voltage.txt", "w+");
    //  写入标题
    fputs("  Real time voltage data\n", file_fd);
    fputs("  time            v1            v2            v3\n", file_fd);
    fclose(file_fd);
    Chart_Init();
}

Widget::~Widget()
{
    delete ui;
}



void Widget::on_pushButton_clicked()
{
    //如果串口没有被打开
    if( openflag != 1 ){
        QSerialPort::BaudRate baudRate;
        QSerialPort::DataBits dataBits;
        QSerialPort::StopBits stopBits;
        QSerialPort::Parity checkBits;

        //判断用户选择的波特率，并将选择的波特率写入串口配置
        if(ui->baudrateCb->currentText() == "2400"){
            baudRate = QSerialPort::Baud2400;
        }
        if(ui->baudrateCb->currentText() == "4800"){
            baudRate = QSerialPort::Baud4800;
        }
        if(ui->baudrateCb->currentText() == "9600"){
            baudRate = QSerialPort::Baud9600;
        }
        if(ui->baudrateCb->currentText() == "19200"){
            baudRate = QSerialPort::Baud19200;
        }
        if(ui->baudrateCb->currentText() == "38400"){
            baudRate = QSerialPort::Baud38400;
        }
        if(ui->baudrateCb->currentText() == "57600"){
            baudRate = QSerialPort::Baud57600;
        }
        if(ui->baudrateCb->currentText() == "115200"){
            baudRate = QSerialPort::Baud115200;
        }

        dataBits = QSerialPort::Data8;      //初始化串口数据位为8位
        stopBits = QSerialPort::OneStop;    //初始化串口停止位为1位
        checkBits = QSerialPort::NoParity;  //初始化串口校验为不校验

        serialport->setPortName(ui->serialCb->currentText());
        serialport->setBaudRate(baudRate);
        serialport->setDataBits(dataBits);
        serialport->setStopBits(stopBits);
        serialport->setParity(checkBits);
        //打开串口
        if(serialport->open(QIODevice::ReadWrite) == true){
            //打开串口提示成功 按钮名字改变
            ui->pushButton->setText("关闭串口");
            openflag = 1;
        }
        else{
            //打开串口失败提示
            QMessageBox::critical(this,"提示","打开失败");
        }
    }
    //如果串口被打开
    else{
        //关闭串口
        serialport->close();
        ui->pushButton->setText("打开串口");
        //变量置0
        openflag = 0;
    }
}
/*
*   串口数据格式
*   printf("%.2f,%.2f,%.2f\n",data1,data2,data3);
*/

void Widget::serialReadData_slot()
{
    // 定义文件指针
    FILE *file_fd;
    //  定义存储缓冲区
    char str[256];
    //  打开文件
    file_fd = fopen("voltage.txt", "a");
    if(file_fd==NULL)             /*判断文件是否打开成功*/
                 qDebug() << "File open error";          /*提示打开不成功*/
    //  实例化一个时间类
    QDateTime currentTime = QDateTime::currentDateTime();
    //设置坐标轴的线式范围
    chart->axisX()->setMin(QDateTime::currentDateTime().addSecs(-60*1));
    chart->axisX()->setMax(QDateTime::currentDateTime().addMSecs(0));
    //创建了一个时间对象，表示午夜零点，使用QTime::currentTime()方法获取当前时间，并计算与午夜零点之间的秒数差，差值会作为种子值传递给qsrand()函数
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
    QByteArray buf;
    float floatValue = 0.0;
    //读取串口缓冲区上一行的数据
    buf = QByteArray(serialport->readLine());
    //将数据从“，”隔开
    QList<QByteArray> myStringList = buf.split(',');
    //将分离后的数据显示到对应控件上
    if( myStringList.size() == 3 ){
        //  将分离出来的数据显示到相应的控件上
        ui->temp1Edit->setText(myStringList.at(0));
        ui->temp2Edit->setText(myStringList.at(1));
        ui->temp3Edit->setText(myStringList.at(2));
        //  将读取到的char温度值转化为float
        floatValue = myStringList.at(0).toFloat();
        //  显示到坐标轴
        series1->append(currentTime.toMSecsSinceEpoch() , floatValue);
        floatValue = myStringList.at(1).toFloat();
        series2->append(currentTime.toMSecsSinceEpoch() , floatValue);
        floatValue = myStringList.at(2).toFloat();
        series3->append(currentTime.toMSecsSinceEpoch() , floatValue);
        //  将要写入的内容整合成成字符串
        sprintf(str, "%s       %.2f      %.2f     %.2f\n",\
                QTime::currentTime().toString().toStdString().c_str(),\
                myStringList.at(0).toFloat(),myStringList.at(1).toFloat(),\
                myStringList.at(2).toFloat());
        //  写入
        fputs(str, file_fd);
        fclose(file_fd);
    }
}

//"刷新串口"按钮槽函数
void Widget::on_pushButton_2_clicked()
{
    QStringList serialNumPort;
    //串口未打开
    if(openflag != 1){
        //清除上次扫描并显示在ui->serialCb说的串口名
        ui->serialCb->clear();
        //重新扫描
        foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
            serialNumPort << info.portName();
        }
        //扫描结果显示
        ui->serialCb->addItems(serialNumPort);
    }
}

//  Chart初始化函数
void Widget::Chart_Init()
{
    //  创建了一个QPen对象、线条颜色为深红色、条的宽度为3个像素、线条的样式为实线、线条的端点样式为圆形端点、线条的连接样式为圆角连接
    QPen peny(Qt::darkRed , 3 , Qt::SolidLine , Qt::RoundCap , Qt::RoundJoin);
    //  实例化新的chart
    chart = new QtCharts::QChart();
    chart->setTitle("实时电压");
//    chart->setTitleFont(QFont::setPointSize());
    //  实例化线条
    series1 = new QtCharts::QSplineSeries();
    series2 = new QtCharts::QSplineSeries();
    series3 = new QtCharts::QSplineSeries();

    //  实例化X Y轴参数对象
    axisX = new QtCharts::QDateTimeAxis();
    axisY = new QtCharts::QValueAxis();

    // 设置series1曲线的颜色为红色
    QPen pen1(Qt::red);
    series1->setPen(pen1);
    // 设置series2曲线的颜色为蓝色
    QPen pen2(Qt::blue);
    series2->setPen(pen2);
    // 设置series3曲线的颜色为绿色
    QPen pen3(Qt::green);
    series3->setPen(pen3);

    chart->legend()->hide();                //隐藏图例
    chart->addSeries(series1);              //把线1添加到chart中
    chart->addSeries(series2);              //把线2添加到chart中
    chart->addSeries(series3);              //把线3添加到chart中

    axisX->setTickCount(7);                 //设置坐标轴格数
    axisY->setTickCount(5);
    axisX->setFormat("hh:mm:ss");           //设置线式格式
    axisY->setMin(0);                       //设置最小值
    axisY->setMax(10);
    axisX->setTitleText("时间");             //设置X轴名

    //  是将axisY坐标轴的线条颜色设置为Qt中的darkGray颜色
//    axisY->setLinePenColor(QColor(Qt::darkGray));       //设置坐标轴颜色
    //  是将axisY坐标轴的网格线颜色设置为Qt中的darkGray颜色
//    axisY->setGridLineColor(QColor(Qt::darkGray));
//    axisY->setGridLineVisible(false);        //设置Y轴网格不显示
    //  是将axisX坐标轴的线条颜色设置为Qt中的darkGray颜色
//    axisX->setLinePenColor(QColor(Qt::darkGray));       //设置坐标轴颜色
    //  是将axisX坐标轴的网格线颜色设置为Qt中的darkGray颜色
//    axisX->setGridLineColor(QColor(Qt::darkGray));
//    axisX->setGridLineVisible(false);        //设置X轴网格不显示

    axisY->setLinePen(peny);
    axisX->setLinePen(peny);
    //  将axisX添加到chart中，并将该轴设置在图表的底部
    chart->addAxis(axisX , Qt::AlignBottom);
    //  将axisY添加到chart中，并将该轴设置在图表的左侧
    chart->addAxis(axisY , Qt::AlignLeft);
    //  将线series1绑定到设置好的X Y轴
    series1->attachAxis(axisX);
    series1->attachAxis(axisY);
    //  将线series2绑定到设置好的X Y轴
    series2->attachAxis(axisX);
    series2->attachAxis(axisY);
    //  将线series3绑定到设置好的X Y轴
    series3->attachAxis(axisX);
    series3->attachAxis(axisY);

    //  用于创建一个QChartView对象，并将QChart对象绑定添加到一个QWidget上
    QtCharts::QChartView *chartView = new QtCharts::QChartView(chart, ui->widget);
    //  将QChartView的渲染选项设置为抗锯齿，让图表的边缘看起来更加平滑
    chartView->setRenderHint(QPainter::Antialiasing);
    //  将QChartView的位置和大小设置为(0, 0)开始，宽度为700，高度为350
    chartView->setGeometry(0, 0, 600, 450);

}


